#include "./render.hpp"

namespace qbe::render {

void create_viewer(ecs::World& world, entt::registry& reg, ecs::Commands commands, ecs::Resource<vsg::ref_ptr<HandleBundle>> handles,
                   ecs::Query query) {
  auto viewer = query.get_resource<vsg::ref_ptr<vsgQt::Viewer>>();
  auto windowTraits = query.get_resource<vsg::ref_ptr<vsg::WindowTraits>>();
  auto options = query.get_resource<vsg::ref_ptr<vsg::Options>>();
  // auto window = query.get_resource<vsgQt::Window*>();
  auto& model = query.get_resource<Model>();

  commands.insert_resources(options);
  commands.insert_resources(windowTraits);

  auto& scene = model.scene;

  model.axis_group = vsg::Group::create();
  scene->addChild(model.axis_group);

  auto transform = vsg::MatrixTransform::create();
  scene->addChild(transform);

  model.edit_group = vsg::Group::create();
  transform->addChild(model.edit_group);

  model.select_group = vsg::Group::create();
  transform->addChild(model.select_group);

  model.cell_group = vsg::Group::create();
  transform->addChild(model.cell_group);

  commands.spawn(SceneTag{}, viewer, scene, options);
  // {
  //   auto width_half = static_cast<double>(windowTraits->width / 2);
  //   auto height_half = static_cast<double>(windowTraits->height / 2);
  //   auto ortho = vsg::Orthographic::create(-width_half, width_half, -height_half, height_half, 0.0f, 10.0f);
  //   auto lookAt = vsg::LookAt::create(vsg::dvec3(0.0, 0.0, 5.0), vsg::dvec3(0.0, 0.0, 0.0), vsg::dvec3(0.0, 1.0, 0.0));
  //   auto viewport = vsg::ViewportState::create(0, 0, windowTraits->width, windowTraits->height);
  //   auto camera = vsg::Camera::create(ortho, lookAt, viewport);
  //   auto commandGraph = vsg::createCommandGraphForView(*window, camera, scene);
  //   commands.spawn(SceneTag{}, viewer, window, camera, scene, options);
  //   viewer->addRecordAndSubmitTaskAndPresentation({commandGraph});
  //   model.camera = camera;
  // }

  // {
  //   auto width_half = static_cast<double>(windowTraits->width / 2);
  //   auto height_half = static_cast<double>(windowTraits->height / 2);
  //   auto ortho = vsg::Orthographic::create(-width_half, width_half, -height_half, height_half, 0.0f, 10.0f);
  //   auto lookAt = vsg::LookAt::create(vsg::dvec3(0.0, 0.0, 5.0), vsg::dvec3(0.0, 0.0, 0.0), vsg::dvec3(0.0, 1.0, 0.0));
  //   auto viewport = vsg::ViewportState::create(0, 0, windowTraits->width, windowTraits->height);
  //   auto camera = vsg::Camera::create(ortho, lookAt, viewport);
  //   auto commandGraph = vsg::createCommandGraphForView(*model.map_window, camera, scene);
  //   viewer->addRecordAndSubmitTaskAndPresentation({commandGraph});
  //   model.map_camera = camera;
  // }

  // 关闭viewer更新, 在系统运行时手动更新
  // viewer->compile();

  viewer->addEventHandler(handles.get());
  // viewer->addEventHandler(vsg::CloseHandler::create(viewer));

  commands.spawn(SceneTag{}, transform);

  // model.window = window;
  model.viewer = viewer;
  model.windowTraits = windowTraits;
  model.options = options;
  model.scene = scene;
  model.transform = transform;
}

void handle_event(entt::registry& reg) {
  // SPDLOG_INFO("FPS Start-------------->");
  // auto view = reg.view<vsg::ref_ptr<vsgQt::Viewer>>();
  // for (auto [e, viewer] : view.each()) {
  //   viewer->handleEvents();
  // }
}

void update_render(entt::registry& reg) {
  // auto view = reg.view<vsg::ref_ptr<vsgQt::Viewer>>();
  // for (auto [e, viewer] : view.each()) {
  //   // viewer->render();
  //   // if (viewer->advanceToNextFrame(vsg::Viewer::UseTimeSinceStartPoint)) {
  //   if (viewer->advanceToNextFrame()) {
  //     viewer->update();
  //     viewer->recordAndSubmit();
  //     viewer->present();
  //   }
  //   // viewer->requests = 0;
  // }
  // SPDLOG_INFO("FPS END-------------->");
}

void update_camera(entt::registry& reg, ecs::Query query, ecs::Resource<vsg::ref_ptr<vsg::WindowTraits>> res_traits) {
  // auto& axis = query.get_resource<axis::Axis>();
  // auto& handle = query.get_resource<vsg::ref_ptr<input::HandleBundle>>();
  // // auto& traits = query.get_resource<vsg::ref_ptr<vsg::WindowTraits>>();
  // auto& cell = query.get_resource<qlib::Cell::s_ptr>();

  // auto update_cam = [&](vsg::ref_ptr<vsg::WindowTraits> traits) {
  //   auto viewport = vsg::ViewportState::create(0, 0, traits->width, traits->height);
  //   auto width_half = static_cast<double>(traits->width / 2);
  //   auto height_half = static_cast<double>(traits->height / 2);
  //   auto ortho = vsg::Orthographic::create(-width_half, width_half, -height_half, height_half, 0.0f, 10.0f);
  //   auto lookAt = vsg::LookAt::create(vsg::dvec3(0.0, 0.0, 5.0), vsg::dvec3(0.0, 0.0, 0.0), vsg::dvec3(0.0, 1.0, 0.0));
  //   auto new_camera = vsg::Camera::create(ortho, lookAt, viewport);
  //   auto view = reg.view<SceneTag, vsg::ref_ptr<vsg::Camera>, vsg::ref_ptr<vsgQt::Viewer>>();
  //   for (auto [e, camera, viewer] : view.each()) {
  //     (*camera) = (*new_camera);
  //     // viewer->compile();
  //   }
  // };

  // auto update_transform = [&]() {
  //   auto t_matrix = vsg::translate(vsg::vec3(axis.gl_dx, axis.gl_dy, 0.0));
  //   auto s_matrix = vsg::scale(vsg::vec3(axis.scale, axis.scale, 1.0));
  //   for (auto [e, transform] : reg.view<render::SceneTag, vsg::ref_ptr<vsg::MatrixTransform>>().each()) {
  //     transform->matrix = t_matrix * s_matrix;
  //   }
  // };

  // auto axis_adapt = [&]() {
  //   auto box = cell->bounding_box();
  //   auto max = box[1];
  //   auto min = box[0];
  //   if (max.x <= min.x || max.y <= min.y) {
  //     min -= 0.5;
  //     max += 0.5;
  //   }
  //   axis.adaptBox(min.x, min.y, max.x, max.y);
  // };

  // if (handle->mouse_wheel || handle->mouse_move || handle->mouse_press || handle->mouse_release) {
  //   update_cam(res_traits.get());
  //   // 更新版图变换矩阵
  //   update_transform();
  // }

  // uint32_t x, y, width, height;
  // if (handle->resized(&x, &y, &width, &height)) {

  //   res_traits.get()->x = x;
  //   res_traits.get()->y = y;
  //   res_traits.get()->width = width;
  //   res_traits.get()->height = height;

  //   auto view = reg.view<SceneTag, vsgQt::Window*>();
  //   for (auto [e, window] : view.each()) {
  //     window->traits->x = x;
  //     window->traits->y = y;
  //     window->traits->width = width;
  //     window->traits->height = height;
  //     update_cam(window->traits);
  //   }

  //   // 画板自适应
  //   axis_adapt();
  //   // 更新版图变换矩阵
  //   update_transform();
  // }

  // int32_t mx, my;
  // if (handle->mouseMoved(&mx, &my)) {}
}

void add_widget(entt::registry& reg, ecs::Resource<State> state, ecs::Resource<QVBoxLayout*> ui_layout) {
  // if (state.get() == State::AddWidget) {
  //   // auto view = reg.view<render::SceneTag, QWidget*>();
  //   // for (auto [e, widget] : view.each()) {
  //   //   ui_layout.get()->addWidget(widget);
  //   // }
  //   state.get() = State::None;
  // }
}

void add_transform(ecs::Query query) {
  // auto& render_model = query.get_resource<Model>();
  // render_model.scene->addChild(render_model.transform);
}

void Render ::build(ecs::App& app) {
  app.init_resource<Model>(Model{});
  app.init_resource<State>(State::AddWidget);

  app.add_systems<ecs::stage::PreStartup>(create_viewer);
  app.add_systems<ecs::stage::PostStartup>(add_transform);
  // app.add_systems<ecs::stage::Update>(update_camera);
};

}  // namespace qbe::render
